#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#define PORT 2080
#define BREAK 5

int main(int argc, char** argv) {
	int received, count, stop, port, pre, order;
	int sockfd, client_sockfd;
	size_t len;
	double time_dif;
	time_t start, end;
	struct sockaddr_in serv_addr, client_addr;

	port = PORT;

	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		fprintf(stderr, "No socket");
		perror(NULL);
		exit(1);
	}

	if (argc == 2)
		port = atoi(argv[1]);

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);


	if ((bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0)
		fprintf(stderr, "Failed to bind.\n");

	printf("Up on port %d\n", port);

	for (;;) {
		len = sizeof(client_addr);
		stop = 0;
		count = 0;
		order = 0;
		pre = -1;
		time(&start);
		while (recvfrom(sockfd, &received, sizeof(int), 0, (struct sockaddr *)&client_addr, &len) > 0) {
			printf("%d\n", received);
			if (received == -1)
				stop++;
			else
			{
				if (received < pre)
					order++;
				count++;
				stop = 0;
				pre = received;
			}
			if (stop == BREAK)
			{
				break;
			}
		}
		time(&end);
		time_dif = difftime(end, start);
		/* TODO: send back read packets */
		printf("Total: %d\n", count);
		printf("Out of Order: %d\n", order);
		printf("Time: %.2f\n", time_dif);
		if (stop == BREAK)	
			break;

		close(client_sockfd);	
	}
	
	return 0;
}
